{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:root:\n",
      "DeepCTR version 0.8.4 detected. Your version is 0.8.1.\n",
      "Use `pip install -U deepctr` to upgrade.Changelog: https://github.com/shenweichen/DeepCTR/releases/tag/v0.8.4\n"
     ]
    }
   ],
   "source": [
    "#导包\n",
    "import pandas as pd\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from deepctr.models import DeepFM\n",
    "from deepctr.feature_column import SparseFeat,get_feature_names"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据读取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112486027</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>29</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112484676</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>32</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112484819</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>47</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112484727</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>50</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112484580</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048570</th>\n",
       "      <td>7120</td>\n",
       "      <td>168</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1175543061</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048571</th>\n",
       "      <td>7120</td>\n",
       "      <td>253</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1175542225</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048572</th>\n",
       "      <td>7120</td>\n",
       "      <td>260</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1175542035</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048573</th>\n",
       "      <td>7120</td>\n",
       "      <td>261</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1175543376</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048574</th>\n",
       "      <td>7120</td>\n",
       "      <td>266</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1175542454</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1048575 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         userId  movieId  rating   timestamp\n",
       "0             1        2     3.5  1112486027\n",
       "1             1       29     3.5  1112484676\n",
       "2             1       32     3.5  1112484819\n",
       "3             1       47     3.5  1112484727\n",
       "4             1       50     3.5  1112484580\n",
       "...         ...      ...     ...         ...\n",
       "1048570    7120      168     5.0  1175543061\n",
       "1048571    7120      253     4.0  1175542225\n",
       "1048572    7120      260     5.0  1175542035\n",
       "1048573    7120      261     4.0  1175543376\n",
       "1048574    7120      266     3.5  1175542454\n",
       "\n",
       "[1048575 rows x 4 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data= pd.read_csv('ratings.csv')\n",
    "data#数据一共有4列 userId代表用户的ID movieId代表电影的ID  rating表示评分 timestamp表示时间戳"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>340880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>28</td>\n",
       "      <td>3.5</td>\n",
       "      <td>340785</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>31</td>\n",
       "      <td>3.5</td>\n",
       "      <td>340801</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>46</td>\n",
       "      <td>3.5</td>\n",
       "      <td>340790</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>49</td>\n",
       "      <td>3.5</td>\n",
       "      <td>340774</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048570</th>\n",
       "      <td>7119</td>\n",
       "      <td>163</td>\n",
       "      <td>5.0</td>\n",
       "      <td>494540</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048571</th>\n",
       "      <td>7119</td>\n",
       "      <td>247</td>\n",
       "      <td>4.0</td>\n",
       "      <td>494524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048572</th>\n",
       "      <td>7119</td>\n",
       "      <td>254</td>\n",
       "      <td>5.0</td>\n",
       "      <td>494519</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048573</th>\n",
       "      <td>7119</td>\n",
       "      <td>255</td>\n",
       "      <td>4.0</td>\n",
       "      <td>494545</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1048574</th>\n",
       "      <td>7119</td>\n",
       "      <td>260</td>\n",
       "      <td>3.5</td>\n",
       "      <td>494530</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1048575 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         userId  movieId  rating  timestamp\n",
       "0             0        1     3.5     340880\n",
       "1             0       28     3.5     340785\n",
       "2             0       31     3.5     340801\n",
       "3             0       46     3.5     340790\n",
       "4             0       49     3.5     340774\n",
       "...         ...      ...     ...        ...\n",
       "1048570    7119      163     5.0     494540\n",
       "1048571    7119      247     4.0     494524\n",
       "1048572    7119      254     5.0     494519\n",
       "1048573    7119      255     4.0     494545\n",
       "1048574    7119      260     3.5     494530\n",
       "\n",
       "[1048575 rows x 4 columns]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sparse_features = [\"movieId\", \"userId\", \"timestamp\"]#准备特征\n",
    "target = ['rating']#准备标签\n",
    "#特征数值化 data里面3个特征都用LabelEncoder处理一下 就是把特征里面的值 从0到n开始编号\n",
    "for f in  sparse_features:\n",
    "    transfor = LabelEncoder()\n",
    "    data[f] = transfor.fit_transform(data[f])\n",
    "data    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/initializers.py:143: calling RandomNormal.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/initializers.py:143: calling RandomNormal.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[SparseFeat(name='movieId', vocabulary_size=14026, embedding_dim=4, use_hash=False, dtype='int32', embeddings_initializer=<tensorflow.python.keras.initializers.RandomNormal object at 0x7fd194d00b90>, embedding_name='movieId', group_name='default_group', trainable=True),\n",
       " SparseFeat(name='userId', vocabulary_size=7120, embedding_dim=4, use_hash=False, dtype='int32', embeddings_initializer=<tensorflow.python.keras.initializers.RandomNormal object at 0x7fd124cbe250>, embedding_name='userId', group_name='default_group', trainable=True),\n",
       " SparseFeat(name='timestamp', vocabulary_size=822889, embedding_dim=4, use_hash=False, dtype='int32', embeddings_initializer=<tensorflow.python.keras.initializers.RandomNormal object at 0x7fd124cbe9d0>, embedding_name='timestamp', group_name='default_group', trainable=True)]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#生成词向量  计算每个特征中的 不同特征值的个数\n",
    "fixlen_feature_columns = [SparseFeat(feat, vocabulary_size=data[feat].nunique()) for feat in sparse_features]\n",
    "fixlen_feature_columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'list'>\n",
      "<class 'deepctr.feature_column.SparseFeat'> \n",
      " SparseFeat(name='movieId', vocabulary_size=14026, embedding_dim=4, use_hash=False, dtype='int32', embeddings_initializer=<tensorflow.python.keras.initializers.RandomNormal object at 0x7fd194d00b90>, embedding_name='movieId', group_name='default_group', trainable=True) \n",
      "\n",
      "<class 'deepctr.feature_column.SparseFeat'> \n",
      " SparseFeat(name='userId', vocabulary_size=7120, embedding_dim=4, use_hash=False, dtype='int32', embeddings_initializer=<tensorflow.python.keras.initializers.RandomNormal object at 0x7fd124cbe250>, embedding_name='userId', group_name='default_group', trainable=True) \n",
      "\n",
      "<class 'deepctr.feature_column.SparseFeat'> \n",
      " SparseFeat(name='timestamp', vocabulary_size=822889, embedding_dim=4, use_hash=False, dtype='int32', embeddings_initializer=<tensorflow.python.keras.initializers.RandomNormal object at 0x7fd124cbe9d0>, embedding_name='timestamp', group_name='default_group', trainable=True) \n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(type(fixlen_feature_columns))#fixlen_feature_columns是个list类型  里面的元素是deepctr.feature_column.SparseFeat类型\n",
    "for i in fixlen_feature_columns:\n",
    "    print(type(i),'\\n',i,'\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['movieId', 'userId', 'timestamp'] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "linear_feature_columns = fixlen_feature_columns\n",
    "dnn_feature_columns = fixlen_feature_columns\n",
    "feature_names = get_feature_names(linear_feature_columns + dnn_feature_columns)\n",
    "print(feature_names,type(feature_names))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 划分数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>781276</th>\n",
       "      <td>5197</td>\n",
       "      <td>1586</td>\n",
       "      <td>3.5</td>\n",
       "      <td>234017</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>839472</th>\n",
       "      <td>5593</td>\n",
       "      <td>2831</td>\n",
       "      <td>3.0</td>\n",
       "      <td>86409</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>775489</th>\n",
       "      <td>5156</td>\n",
       "      <td>2798</td>\n",
       "      <td>3.0</td>\n",
       "      <td>564688</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>692126</th>\n",
       "      <td>4589</td>\n",
       "      <td>13446</td>\n",
       "      <td>4.0</td>\n",
       "      <td>798121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>108617</th>\n",
       "      <td>740</td>\n",
       "      <td>8638</td>\n",
       "      <td>4.0</td>\n",
       "      <td>524674</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>602048</th>\n",
       "      <td>4033</td>\n",
       "      <td>4708</td>\n",
       "      <td>3.0</td>\n",
       "      <td>580199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>379317</th>\n",
       "      <td>2570</td>\n",
       "      <td>875</td>\n",
       "      <td>4.0</td>\n",
       "      <td>241641</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>144487</th>\n",
       "      <td>970</td>\n",
       "      <td>1165</td>\n",
       "      <td>3.0</td>\n",
       "      <td>535523</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>862365</th>\n",
       "      <td>5766</td>\n",
       "      <td>3690</td>\n",
       "      <td>5.0</td>\n",
       "      <td>388073</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>137101</th>\n",
       "      <td>919</td>\n",
       "      <td>167</td>\n",
       "      <td>1.0</td>\n",
       "      <td>22785</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>838860 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        userId  movieId  rating  timestamp\n",
       "781276    5197     1586     3.5     234017\n",
       "839472    5593     2831     3.0      86409\n",
       "775489    5156     2798     3.0     564688\n",
       "692126    4589    13446     4.0     798121\n",
       "108617     740     8638     4.0     524674\n",
       "...        ...      ...     ...        ...\n",
       "602048    4033     4708     3.0     580199\n",
       "379317    2570      875     4.0     241641\n",
       "144487     970     1165     3.0     535523\n",
       "862365    5766     3690     5.0     388073\n",
       "137101     919      167     1.0      22785\n",
       "\n",
       "[838860 rows x 4 columns]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将数据集切分成训练集和测试集\n",
    "train, test = train_test_split(data, test_size=0.2)\n",
    "train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>273284</th>\n",
       "      <td>1875</td>\n",
       "      <td>1299</td>\n",
       "      <td>3.0</td>\n",
       "      <td>404817</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>967676</th>\n",
       "      <td>6509</td>\n",
       "      <td>1700</td>\n",
       "      <td>4.0</td>\n",
       "      <td>111999</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>190938</th>\n",
       "      <td>1300</td>\n",
       "      <td>181</td>\n",
       "      <td>2.0</td>\n",
       "      <td>44270</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>970542</th>\n",
       "      <td>6539</td>\n",
       "      <td>15</td>\n",
       "      <td>3.0</td>\n",
       "      <td>138762</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>674948</th>\n",
       "      <td>4492</td>\n",
       "      <td>865</td>\n",
       "      <td>3.0</td>\n",
       "      <td>159428</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>813660</th>\n",
       "      <td>5419</td>\n",
       "      <td>1475</td>\n",
       "      <td>4.0</td>\n",
       "      <td>205705</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>759592</th>\n",
       "      <td>5062</td>\n",
       "      <td>9828</td>\n",
       "      <td>4.0</td>\n",
       "      <td>616011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>395728</th>\n",
       "      <td>2701</td>\n",
       "      <td>13433</td>\n",
       "      <td>3.5</td>\n",
       "      <td>786994</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20576</th>\n",
       "      <td>155</td>\n",
       "      <td>1812</td>\n",
       "      <td>3.0</td>\n",
       "      <td>200067</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>265286</th>\n",
       "      <td>1835</td>\n",
       "      <td>282</td>\n",
       "      <td>4.0</td>\n",
       "      <td>8533</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>209715 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        userId  movieId  rating  timestamp\n",
       "273284    1875     1299     3.0     404817\n",
       "967676    6509     1700     4.0     111999\n",
       "190938    1300      181     2.0      44270\n",
       "970542    6539       15     3.0     138762\n",
       "674948    4492      865     3.0     159428\n",
       "...        ...      ...     ...        ...\n",
       "813660    5419     1475     4.0     205705\n",
       "759592    5062     9828     4.0     616011\n",
       "395728    2701    13433     3.5     786994\n",
       "20576      155     1812     3.0     200067\n",
       "265286    1835      282     4.0       8533\n",
       "\n",
       "[209715 rows x 4 columns]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(838860, 4) (209715, 4)\n"
     ]
    }
   ],
   "source": [
    "print(train.shape,test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'movieId': array([  337,    93, 10713, ...,    46,   360,  6579]),\n",
       " 'userId': array([6824, 4128, 5972, ..., 5953, 1014, 3915]),\n",
       " 'timestamp': array([    32, 411740, 822450, ..., 664008, 311116, 652442])}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_model_input = {name:train[name].values for name in feature_names}\n",
    "train_model_input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'movieId': array([  49, 2538, 2978, ..., 1596,  461,    5]),\n",
       " 'userId': array([5671, 4807, 2949, ..., 4761, 5209, 5671]),\n",
       " 'timestamp': array([ 10325, 386081, 182760, ..., 283513, 115178,  10331])}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_model_input = {name:test[name].values for name in feature_names}\n",
    "test_model_input"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DeepFM建模与训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.7/site-packages/tensorflow/python/framework/indexed_slices.py:434: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.\n",
      "  \"Converting sparse IndexedSlices to a dense Tensor of unknown shape. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2622/2622 [==============================] - 79s 30ms/step - loss: 1.2626 - mse: 1.2574 - val_loss: 1.1250 - val_mse: 1.1146\n"
     ]
    }
   ],
   "source": [
    "# 使用DeepFM进行训练\n",
    "#linear_feature_columns线性部分用FM dnn_feature_columns高阶部分用DNN  task='regression'表示回归任务\n",
    "model = DeepFM(linear_feature_columns, dnn_feature_columns, task='regression')\n",
    "#优化器用adam 评价指标用mse\n",
    "model.compile(\"adam\", \"mse\", metrics=['mse'] )\n",
    "#train_model_input作为训练集 rating作为标签值\n",
    "history = model.fit(train_model_input, train['rating'].values, batch_size=256, epochs=1, verbose=True, validation_split=0.2 )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模型预测与评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mse: 1.1079\n"
     ]
    }
   ],
   "source": [
    "# 使用DeepFM进行预测\n",
    "pred= model.predict(test_model_input, batch_size=256)\n",
    "# 输出RMSE或MSE\n",
    "mse = round(mean_squared_error(test['rating'].values, pred), 4)\n",
    "print(\"mse:\", mse)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
